package com.commods.main.view.components.historicalChart.proto.mock
{
	import com.commods.main.view.components.historicalChart.proto.temp.TempUtils;
	import com.commods.main.view.components.historicalChart.proto.vo.TradeData;
	import com.commods.main.view.components.historicalChart.proto.vo.TradeHistoryData;
	
	import flash.events.DataEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import mx.collections.ArrayCollection;
	import mx.events.DynamicEvent;
	
	[Event(name="message", type="mx.events.DynamicEvent")]
	public class HDataGenerator extends EventDispatcher
	{
		public static const EVT_MESSAGE:String = "message";
		private static const INTERVAL:Number = 400;
		private var _timer:Timer;
		[Bindable]public var TRADE_MIN_DIFF:Number=10;
		[Bindable]public var TRADE_MAX:Number=100;
		[Bindable]public var TRADE_MIN:Number=0;
		private var currentVO:TradeData;
		
		public function HDataGenerator(target:IEventDispatcher=null)
		{
			super(target);
			init();
		}

		public var todayDate:Date, todayOpen:Number;
		private function init():void{
			_timer = new Timer(INTERVAL);
			_timer.addEventListener(TimerEvent.TIMER, onTimeTick);
			_timer.start();
			
			TRADE_MIN = TempUtils.rndRangeInt(100, 5000);
			TRADE_MAX = TRADE_MIN + TempUtils.rndRangeInt(100, 1000); 
			TRADE_MIN_DIFF = Math.floor((TRADE_MAX - TRADE_MIN)/5);
		
			var vo:TradeData = new TradeData();
			var midnight:Date = new Date();
			midnight.setHours(0, 0, 0, 0);
			vo.time = midnight;
			vo.ask = TempUtils.rndRangeInt(TRADE_MIN, TRADE_MAX);
			vo.bid =  TempUtils.rndRangeInt(TRADE_MIN, vo.ask-TRADE_MIN_DIFF);
			currentVO = vo;
			
			todayDate=currentVO.time;
			todayOpen = (currentVO.ask+currentVO.bid)/2;
		}
		
		public function generateTradeHistory(date:Date, open:Number):ArrayCollection{
			return _generateTradeHistory(date, open);
		}
		
		public function generateTodaysHistory():ArrayCollection{
			var result:ArrayCollection = new ArrayCollection();
			var midnight:Date = new Date();
			midnight.setHours(0, 0, 0, 0);
			var now:Date = new Date();
			var hourAgo:Date = TempUtils.dateAdd("hours", -1);
			
			var interval:Number = 15; //every 15 MINUTES
			
			var curDate:Date = new Date(midnight);
			while(curDate.time<now.time){
				var vo:TradeData = _generateTradeData((Math.random()>0.5), curDate); 
				curDate = TempUtils.dateAdd("minutes", 15, curDate);
				result.addItem(vo);
		
			}
			
			return result;
		}
		
		private function _generateTradeData(askChanged:Boolean, date:Date=null):TradeData{
			var vo:TradeData = new TradeData();
			vo.time = date || new Date();
			if(askChanged){
				vo.bid = currentVO.bid;
				vo.ask = TempUtils.rndRangeInt(vo.bid+TRADE_MIN_DIFF, TRADE_MAX);
			}else{
				vo.ask = currentVO.ask;
				vo.bid = TempUtils.rndRangeInt(TRADE_MIN, vo.ask-TRADE_MIN_DIFF);
				
			}
			return vo;
		}
		
		private function _generateTradeHistory(todayDate:Date, todayOpen:Number, weeksBack:Number=4):ArrayCollection{
		
			var result:ArrayCollection = new ArrayCollection();
			var curClosed:Number = todayOpen;
			//back to yesterday
			var curDate:Date = TempUtils.dateAdd("date", -1, todayDate); 
			curDate.setHours(11, 59, 0, 0);
			//look back for first work-day (skip weekends)
			while(curDate.day==0 || curDate.day==6){
				curDate = TempUtils.dateAdd("date", -1, curDate);
			}
		
			//fill result with 4 working-weeks data from yesterday
			var count:Number = weeksBack;
			while(count>0){
				var isWeekend:Boolean = (curDate.day==0 || curDate.day==6);
				if(isWeekend){
					if(curDate.day==0){
						count--;
					}
					curDate = TempUtils.dateAdd("date", -1, curDate);
					continue;
				}
				
				var hloc:TradeHistoryData = genTradeHistoryDate(curDate, curClosed, TRADE_MIN, TRADE_MAX);
				result.addItem(hloc);
				
				curClosed = hloc.open;
				curDate = TempUtils.dateAdd("date", -1, curDate);
			}
			
			return result;
		}
		
		private function genTradeHistoryDate(date:Date, close:Number, min:Number, max:Number):TradeHistoryData{
			var result:TradeHistoryData = new TradeHistoryData();
			result.date = date;
			result.close = close;
			//rnd
			//low must be the lowest, high must be the highest
			//open - can be smth other
			result.high = TempUtils.rndRangeInt(close, max);
			result.low = TempUtils.rndRangeInt(min, close);
			result.open = TempUtils.rndRangeInt(result.low , result.high);
			return result;
		}
		
		
		
		


		protected function onTimeTick(event:TimerEvent):void{
			//only for 20% cases value changes
			var newVO:TradeData = null;
			var rnd:Number = Math.random();
			var casesRatio:Number = 0.3;
			if(rnd>1-casesRatio/2){
				newVO = _generateTradeData(true);
			}else if(rnd<casesRatio/2){
				newVO= _generateTradeData(false);
			}else{
				//clone old data
				newVO = new TradeData();
				newVO.time = new Date();
				newVO.bid = currentVO.bid;
				newVO.ask =  currentVO.ask;
			}

			
			var dataEvent:DynamicEvent = new DynamicEvent(EVT_MESSAGE);
			dataEvent.vo = currentVO;
			dispatchEvent(dataEvent);
			
			currentVO = newVO;
		}
		

	}
}